package org.jslaughter.main;

import java.util.ArrayList;
import java.util.List;

import org.jslaughter.level.Level;
import org.jslaughter.level.Level1;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.nvframe.NVFramePhysicsGame;
import org.nvframe.component.physics.util.PhysicsDebugDraw;
import org.nvframe.event.EventService;
import org.nvframe.event.eventtype.UpdateEvent;
import org.nvframe.event.eventtype.UpdateListener;
import org.nvframe.factory.EntityFactory;
import org.nvframe.manager.ConfigManager;
import org.nvframe.manager.EntityManager;
import org.nvframe.manager.InputManager;
import org.nvframe.manager.ResourceManager;

public class Main extends NVFramePhysicsGame implements UpdateListener {

	protected ConfigManager configManager = ConfigManager.getInstance();
	
	private List<Level> levels = new ArrayList<Level>();

	public Main() {
		super("jSlaughter - testlevel");
	}

	@Override
	public void init(GameContainer gc) throws SlickException {
		// config manager
		configManager.setFunction("debugMode", true);
		configManager.setFunction("engine_vsync", false);
		configManager.setFunction("engine_physics_drawbodies", false);
		configManager.setFunction("engine_physics_showposition", false);
		configManager.setFunction("engine_soundenabled", false);
		
		new PhysicsDebugDraw(world);

		try {
			// load resources
			ResourceManager.getInstance().loadResources("level1_resources.xml", false);

			// load input commands
			InputManager.getInstance().loadInputKeys("input.xml");
			setPauzeKey(InputManager.getInstance().getInput("game_pauze"));

			// load entities xml
			EntityFactory.getInstance().loadEntitiesFromXml("level1_entities.xml");

			Level1 level1 = new Level1();
			
			level1.createFromXML("level1_layout.xml");
			level1.start();
			
			levels.add(level1);

			// set crosshair to ingame crosshair
			gc.setMouseCursor(ResourceManager.getInstance().getImage("crosshair"), 0, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}

		EventService.getInstance().addEventListener(this);
	}

	public static void main(String[] args) throws SlickException {
		AppGameContainer gc = new AppGameContainer(new Main());

		// engine options
		gc.setVSync(false);
		//gc.setSmoothDeltas(true);
		// gc.setTargetFrameRate(60);
		gc.setDisplayMode(1024, 768, false);
		
		gc.setSoundVolume(.001f);
		gc.setSoundOn(true);
		
		gc.setMusicVolume(.5f);
		gc.setMusicOn(true);
		
		if(gc.supportsMultiSample())
			gc.setMultiSample(4);
		
		//gc.setMouseGrabbed(true);
		
		gc.start();
	}
	
	public void checkFunctionKeys(GameContainer gc) {
		// game options
		Input input = gc.getInput();
		InputManager inputManager = InputManager.getInstance();
		
		// check if a optionkey is pressed
		if (input.isKeyPressed(inputManager.getInput("engine_debugmode")))
			configManager.toggleActive("debugMode");
		
		if (input.isKeyPressed(inputManager.getInput("engine_vsync"))) {
			configManager.toggleActive("engine_vsync");
			gc.setVSync(configManager.getActive("engine_vsync"));
			//gc.setSmoothDeltas(configManager.getActive("engine_vsync"));
		}
		
		if (input.isKeyPressed(inputManager.getInput("engine_physics_drawbodies")))
			configManager.toggleActive("engine_physics_drawbodies");
		
		if (input.isKeyPressed(inputManager.getInput("engine_physics_showposition")))
			configManager.toggleActive("engine_physics_showposition");
		
		if (input.isKeyPressed(inputManager.getInput("engine_soundenabled"))) {
			configManager.toggleActive("engine_soundenabled");
			gc.setSoundOn(configManager.getActive("engine_soundenabled"));
		}
		
		if (input.isKeyPressed(inputManager.getInput("engine_printentities")))
			EntityManager.getInstance().printEntities();
		
		if(input.isKeyPressed(inputManager.getInput("engine_showkeybindings")))
			InputManager.getInstance().showAllBindings();
	}
	
	@Override
	public void onUpdate(UpdateEvent event) {
		checkFunctionKeys(event.getGc());
	}

}
